﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reactive.Subjects;
using Machine.Specifications;
using Moq;
using RxHeat.Tracing;
using It = Moq.It;

namespace RxHeat.Tests.Tracing
{
    public class when_tracing_a_stream : TraceOutput
    {
        protected static readonly Guid _testInstance2 = Guid.NewGuid();
        protected static readonly List<string> _onNextValues = new List<string>();

        private Because of = () =>
            {
                Debug.WriteLine("when_tracing_a_stream._testInstance2:" + _testInstance2);
                const int length = 5;
                for (int i = 0; i < length; i++)
                {
                    _onNextValues.Add(Guid.NewGuid().ToString());
                }

                var subject = new Subject<string>();
                subject.Subscribe("when_tracing_a_stream", null, null, null, true);
                _onNextValues.ForEach(subject.OnNext);
                subject.OnCompleted();

                _output.ForEach(x => Debug.WriteLine(x));
            };
    }

    [Subject(typeof (ObservableExtensions))]
    public class when_using_TraceManager : when_tracing_a_stream
    {
        private Establish _ = () =>
            {
                Debug.WriteLine("when_tracing_a_stream._testInstance:" + _testInstance);
                TraceManager.AssignTraceListenerFactory(logKey =>
                    {
                        var mock = new Mock<IRxHeatTraceListner>();
                        mock.Setup(i => i.Trace(It.IsAny<TraceDetails>()))
                            .Callback<TraceDetails>(x => _output.Add("TRACE: " + x));
                        return mock.Object;
                    });
            };

        private Behaves_like<B_output_matches_stream_values_specification> _output_matches_stream_values_specification;
    }

    [Subject(typeof (ObservableExtensions))]
    public class when_using_DefaultTracer : when_tracing_a_stream
    {
        private Establish _ = () =>
            {
                Debug.WriteLine("when_tracing_a_stream._testInstance:" + _testInstance);
                var mock = new Mock<IRxHeatTraceListner>();
                mock.Setup(i => i.Trace(It.IsAny<TraceDetails>()))
                    .Callback<TraceDetails>(x => _output.Add("TRACE: " + x));
                TraceManager.AssignDefaultTraceListener(mock.Object);
            };

        //TODO: running this alone would fail.
        private Behaves_like<B_output_matches_stream_values_specification> _output_matches_stream_values_specification;
    }
}